package com.alibaba.cloud.sentinel.feign;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kw.common.core.util.R;
import com.kw.common.core.util.SpringContextHolder;
import feign.FeignException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.lang.Nullable;


import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

@Slf4j
@AllArgsConstructor
public class CommonSentinelFeignFallback<T> implements MethodInterceptor {
	private final Class<T> targetType;
	private final String targetName;
	private final Throwable cause;

	@Nullable
	@Override
	public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
		String errorMessage = cause.getMessage();
		log.error("feign异常:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, errorMessage);
		// 非 FeignException，直接返回
		if (!(cause instanceof FeignException)) {

			return null;
		}


		FeignException exception = (FeignException) cause;


		byte[] content = exception.content();

		String str = StrUtil.str(content, StandardCharsets.UTF_8);

        //此处只是示例，具体可以返回带有业务错误数据的对象
		ObjectMapper objectMapper = SpringContextHolder.getBean(ObjectMapper.class);
		return objectMapper.readValue(str, R.class);
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) {
			return true;
		}
		if (o == null || getClass() != o.getClass()) {
			return false;
		}
		CommonSentinelFeignFallback<?> that = (CommonSentinelFeignFallback<?>) o;
		return targetType.equals(that.targetType);
	}

	@Override
	public int hashCode() {
		return Objects.hash(targetType);
	}
}
